# #!/bin/bash

# # This script is used to deploy bc-storage cluster.

# CUR_DIR="$( cd "$( dirname "$(readlink -f "$0")" )" && pwd )"
# source $CUR_DIR/cluster_IP.conf

# performance=true
# CEPH_SRC_DIR="$HOME/ssd/build-ceph/"
# TARGET_HOST_CEPH_DIR="~/deploy-bcs/ceph"
# TARGET_HOST_REDUNDANCY_DIR="~/ssd/bc-storage/run-redundancy"

# usage() {
#     echo "Usage:"
#     echo "    ./deploy.sh [performance|redundancy|down|gen_obj]"
#     echo "        performance: deploy performance test"
#     echo "        redundancy: deploy redundancy test"
#     echo "        down: down all cluster"
#     echo "        gen_obj: generate rados objects to test"
# }

# deploy_kafka() {
#     echo "Deploy kafka cluster"

#     local org_id=0
#     for node in ${KAFKA_IPs[@]}; do
#         echo "Deploy kafka on $node"
#         ssh $node "mkdir -p ~/deploy-bcs/kafka" && \
#         scp -r $CUR_DIR/kafka $HOST_USER@${node}:~/deploy-bcs/ > /dev/null && \
#         ssh $node "
#             bash deploy-bcs/kafka/deploy_kafka.sh \
#                 -i $node -p $(($KAFKA_PORT_BASE+$org_id)) \
#                 -zp $(($ZOOKEEPER_PORT_BASE+$org_id))
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait

#     echo "Deploy kafka cluster ... done"
# }

# deploy_fabric_network() {
#     echo "Deploy fabric network"

#     bash $CUR_DIR/fabric_network/deploy/deploy_fabric_network.sh up

#     echo "Deploy fabric network ... done"
# }

# deploy_fabric_sdk() {
#     echo "Deploy fabric-sdk"

#     cd $CUR_DIR/fabric_network/deploy
#     bash ./deploy_fabric_sdk.sh server

#     echo "Deploy fabric-sdk ... done"
# }

# restart_ceph() {
#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "Deploy ceph on $node"
#         ssh $node "[ -d ${TARGET_HOST_CEPH_DIR} ] && \
#             rm -rf ${TARGET_HOST_CEPH_DIR}/* || \
#             mkdir -p ${TARGET_HOST_CEPH_DIR}" && \
#         scp $CUR_DIR/ceph-config/deploy_ceph.sh $HOST_USER@${node}:${TARGET_HOST_CEPH_DIR} > /dev/null && \
#         scp $CUR_DIR/cluster_IP.conf $HOST_USER@${node}:${TARGET_HOST_CEPH_DIR}/../ > /dev/null && \
#         ssh $node "
#             bash ${TARGET_HOST_CEPH_DIR}/deploy_ceph.sh \
#                 -i $org_id -p $performance
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait
# }

# check_cephs_status() {
#     echo "Check cephs status"
#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "Check ceph status on $node"
#         local ceph_health=$(
#             ssh $node "
#                 docker exec ceph-demo-${org_id} zsh -c '
#                     source ~/.zshrc; 
#                     timeout 2s ceph health
#                 ' 2>/dev/null
#             " | grep HEALTH_OK
#         )
#         if [ -z "$ceph_health" ]; then
#             echo "No ceph running in [$node]"
#             exit -1
#         fi
#         org_id=$(($org_id+1))
#     done
#     echo "All cephs are running & healthy"
# }

# deploy_ceph() {
#     echo "Deploy ceph cluster"

#     # restart ceph cluster
#     restart_ceph

#     # check cephs status
#     check_cephs_status

#     echo "Deploy ceph cluster ... done"
# }

# deploy_redundancy() {
#     echo "Deploy redundancy"

#     # down redundancy
#     down_redundancy

#     # make redundancy binaray file
#     ssh ${HOST_USER}@${CEPH_IPs[0]} "
#         docker exec ceph-demo-0 zsh -c '
#             source ~/.zshrc
#             cd $CUR_DIR/redundancy/src && \
#             go build -o redundancy
#         '
#     "

#     # distribute redundancy binary file to all nodes
#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "==== send redundancy binary to $node ===="
#         ssh ${HOST_USER}@${node} "
#             [ -d ${TARGET_HOST_REDUNDANCY_DIR} ] && \
#                 rm -rf ${TARGET_HOST_REDUNDANCY_DIR}/* || \
#                 mkdir -p ${TARGET_HOST_REDUNDANCY_DIR}
#             mkdir -p ${TARGET_HOST_REDUNDANCY_DIR}
#         " && \
#         scp $CUR_DIR/redundancy/src/redundancy ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
#         scp -r $CUR_DIR/fabric_network/deploy/crypto-config ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
#         # scp $CUR_DIR/redundancy/hosts_config.sh ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
#         scp $CUR_DIR/cluster_IP.conf ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/../ > /dev/null 2>&1 &
#         org_id=$((org_id+1))
#     done
#     wait

#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "Deploy redundancy on $node"
#         ssh $node "
#             # bash ${TARGET_HOST_REDUNDANCY_DIR}/hosts_config.sh
#             docker exec ceph-demo-${org_id} zsh -c '
#                 ${TARGET_HOST_REDUNDANCY_DIR}/redundancy \
#                     -i $org_id -c ${TARGET_HOST_REDUNDANCY_DIR}/../cluster_IP.conf \
#                     > ${TARGET_HOST_REDUNDANCY_DIR}/redundancy.log 2>&1 &
#             '
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait

#     echo "Deploy redundancy ... done"
# }

# gen_rados_objs_to_test() {
#     echo "Generate rados objects to test"

#     # local org_id=0
#     # for node in ${CEPH_IPs[@]}; do
#     #     echo "Generate rados objects on $node"
#     #     ssh $node "
#     #         docker exec ceph-demo-${org_id} zsh -c '
#     #             source ~/.zshrc;
#     #             ceph osd pool rm testbench testbench --yes-i-really-really-mean-it
#     #             ceph osd pool create testbench 32 32
#     #             ceph osd pool application enable testbench rgw
#     #             rados -p testbench cleanup
#     #         '
#     #     " &
#     #     org_id=$(($org_id+1))
#     # done
#     # wait
    
#     # run rados benchmarks in all orgs
#     local org_id=0
#     local obj_size_in_ceph="4M"
#     [ "$performance" = true ] && obj_size_in_ceph="4K"
#     for node in ${CEPH_IPs[@]}; do
#         ssh $node "
#             docker exec ceph-demo-${org_id} zsh -c '
#                 source ~/.zshrc;
#                 rados bench -p testbench 2 write -t 32 -b ${obj_size_in_ceph} --put-hash-to-fabric --no-cleanup \
#                     > ./testResult/test_write_${obj_size_in_ceph}_with_fabric_org${org_id}.res
#             '
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait

#     # copy test result to local
#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         scp $HOST_USER@${node}:$CEPH_SRC_DIR/ceph-demo-${org_id}/testResult/test_write_${obj_size_in_ceph}_with_fabric_org${org_id}.res \
#             $CUR_DIR/ceph-config/testResult/test_write_${obj_size_in_ceph}_with_fabric_org${org_id}.res > /dev/null
#         org_id=$(($org_id+1))
#     done

#     echo "Generate rados objects to test ... done"
# }

# down_redundancy() {
#     echo "Down redundancy"

#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "Down redundancy on $node"
#         ssh $node "
#             docker exec ceph-demo-${org_id} zsh -c '
#                 kill -9 \$(ps -ef | grep redundancy | grep -v grep | awk \"{print \\\$2}\") > /dev/null 2>&1
#             '
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait

#     echo "Down redundancy ... done"
# }

# down_kafka() {
#     echo "Down kafka cluster"

#     local org_id=0
#     for node in ${KAFKA_IPs[@]}; do
#         echo "Down kafka on $node"
#         ssh $node "
#             bash ~/deploy-bcs/kafka/down_kafka.sh \
#                 -p $(($KAFKA_PORT_BASE+$org_id)) \
#                 -zp $(($ZOOKEEPER_PORT_BASE+$org_id))
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait

#     echo "Down kafka cluster ... done"
# }

# down_fabric_network() {
#     echo "Down fabric network"

#     bash $CUR_DIR/fabric_network/deploy/deploy_fabric_network.sh down

#     echo "Down fabric network ... done"
# }

# down_fabric_sdk() {
#     echo "Down fabric-sdk"

#     cd $CUR_DIR/fabric_network/deploy
#     bash ./deploy_fabric_sdk.sh down

#     echo "Down fabric-sdk ... done"
# }

# down_ceph() {
#     echo "Down ceph cluster"

#     local org_id=0
#     for node in ${CEPH_IPs[@]}; do
#         echo "Down ceph on $node"
#         ssh $node "
#             docker exec ceph-demo-${org_id} zsh -c '
#                 source ~/.zshrc;
#                 cd ./build
#                 bash ../src/stop.sh
#                 rm -rf out dev
#             '
#         " &
#         org_id=$(($org_id+1))
#     done
#     wait
# }

# down_all_cluster() {
#     echo "Down all cluster"

#     # down redundancy
#     down_redundancy

#     # down ceph cluster
#     down_ceph

#     # down fabric-sdk
#     down_fabric_sdk

#     # down fabric network
#     down_fabric_network

#     # down kafka cluster
#     down_kafka

#     echo "Down all cluster ... done"
# }

# main() {
#     echo "Start deploy bc-storage cluster"
#     echo "Performance: $performance"
#     cd $CUR_DIR

#     # # deploy kafka cluster
#     # deploy_kafka

#     # deploy fabric network
#     deploy_fabric_network

#     # deploy fabric-sdk
#     deploy_fabric_sdk

#     # # deploy ceph cluster
#     # deploy_ceph

#     # # deploy redundancy
#     # deploy_redundancy

#     # sleep 12s
    
#     # # gen rados objects to test
#     # gen_rados_objs_to_test

#     echo "Deploy bc-storage cluster ... done"
# }

# if [ $# -ne 1 ]; then
#     usage
#     exit -1
# fi

# while [ $# -ge 1 ]; do
# case $1 in
#     performance)
#         performance=true
#         ;;
#     redundancy)
#         performance=false
#         ;;
#     down)
#         down_all_cluster
#         exit 0
#         ;;
#     gen_obj)
#         performance=false
#         gen_rados_objs_to_test
#         exit 0
#         ;;
#     *)
#         usage
#         exit -1
# esac
# shift
# done

# main

#!/bin/bash

# This script is used to deploy bc-storage cluster.

CUR_DIR="$( cd "$( dirname "$(readlink -f "$0")" )" && pwd )"
cd $CUR_DIR
source $CUR_DIR/cluster_IP.conf

performance=true
WRITE=false
WITH_FABRIC=true
OBJ_SIZE_TO_CEPH=$(echo "4*1024*1024" | bc) # byte, default 256 KB to test redundancy
GEN_OBJ_TIME=5
CEPH_SRC_DIR="$HOME/ssd/build-ceph/"
TARGET_HOST_CEPH_DIR="~/deploy-bcs/ceph"
TARGET_HOST_REDUNDANCY_DIR="~/ssd/bc-storage/run-redundancy"

usage() {
    echo "Usage:"
    echo "    ./deploy.sh [performance|redundancy|down|gen_obj]"
    echo "        performance: deploy performance test"
    echo "        redundancy: deploy redundancy test"
    echo "        down: down all cluster"
    echo "        gen_obj: generate rados objects to test"
}

deploy_kafka() {
    echo "Deploy kafka cluster"

    local org_id=0
    for node in ${KAFKA_IPs[@]}; do
        echo "Deploy kafka on $node"
        ssh $node "mkdir -p ~/deploy-bcs/kafka" && \
        scp -r $CUR_DIR/kafka $HOST_USER@${node}:~/deploy-bcs/ > /dev/null && \
        ssh $node "
            bash deploy-bcs/kafka/deploy_kafka.sh \
                -i $node -p $(($KAFKA_PORT_BASE+$org_id)) \
                -zp $(($ZOOKEEPER_PORT_BASE+$org_id))
        " &
        org_id=$(($org_id+1))
    done
    wait

    echo "Deploy kafka cluster ... done"
}

deploy_fabric_network() {
    echo "Deploy fabric network"

    bash $CUR_DIR/fabric_network/deploy/deploy_fabric_network.sh up

    echo "Deploy fabric network ... done"
}

deploy_fabric_sdk() {
    echo "Deploy fabric-sdk"

    cd $CUR_DIR/fabric_network/deploy
    bash ./deploy_fabric_sdk.sh server

    echo "Deploy fabric-sdk ... done"
}

restart_ceph() {
    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        echo "Deploy ceph on $node"
        ssh $node "[ -d ${TARGET_HOST_CEPH_DIR} ] && \
            rm -rf ${TARGET_HOST_CEPH_DIR}/* || \
            mkdir -p ${TARGET_HOST_CEPH_DIR}" && \
        scp $CUR_DIR/ceph-config/deploy_ceph.sh $HOST_USER@${node}:${TARGET_HOST_CEPH_DIR} > /dev/null && \
        scp $CUR_DIR/cluster_IP.conf $HOST_USER@${node}:${TARGET_HOST_CEPH_DIR}/../ > /dev/null && \
        ssh $node "
            bash ${TARGET_HOST_CEPH_DIR}/deploy_ceph.sh \
                -i $org_id -s $OBJ_SIZE_TO_CEPH
        " && \
        scp $HOST_USER@${node}:~/ssd/build-ceph/ceph-demo-$org_id/build/secret_$org_id.json $CUR_DIR/ceph-config/rgw_s3/ &
        org_id=$(($org_id+1))
    done
    wait
}

check_cephs_status() {
    echo "Check cephs status"
    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        echo "Check ceph status on $node"
        local ceph_health=$(
            ssh $node "
                docker exec ceph-demo-${org_id} zsh -c '
                    source ~/.zshrc; 
                    timeout 2s ceph health
                ' 2>/dev/null
            " | grep HEALTH_OK
        )
        if [ -z "$ceph_health" ]; then
            echo "No ceph running in [$node]"
            exit -1
        fi
        org_id=$(($org_id+1))
    done
    echo "All cephs are running & healthy"
}

deploy_ceph() {
    echo "Deploy ceph cluster"

    # restart ceph cluster
    restart_ceph

    # check cephs status
    check_cephs_status

    echo "Deploy ceph cluster ... done"
}

deploy_redundancy() {
    echo "Deploy redundancy: performance=$performance, write=$WRITE, with_fabric=$WITH_FABRIC"

    # down redundancy
    down_redundancy

    # if [ $performance = true ] && [ $WRITE = true ]; then
    #     return
    # fi

    # make redundancy binaray file
    scp -r $CUR_DIR/redundancy ${HOST_USER}@${CEPH_IPs[0]}:${TARGET_HOST_REDUNDANCY_DIR}/../ > /dev/null 2>&1
    ssh ${HOST_USER}@${CEPH_IPs[0]} "
        docker exec ceph-demo-0 zsh -c '
            source ~/.zshrc
            cd ${TARGET_HOST_REDUNDANCY_DIR}/../redundancy/src && \
            go build -o redundancy
        '
    "
    scp ${HOST_USER}@${CEPH_IPs[0]}:${TARGET_HOST_REDUNDANCY_DIR}/../redundancy/src/redundancy $CUR_DIR/redundancy/src/ > /dev/null 2>&1

    # distribute redundancy binary file to all nodes
    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        echo "==== send redundancy binary to $node ===="
        ssh ${HOST_USER}@${node} "
            [ -d ${TARGET_HOST_REDUNDANCY_DIR} ] && \
                rm -rf ${TARGET_HOST_REDUNDANCY_DIR}/* || \
                mkdir -p ${TARGET_HOST_REDUNDANCY_DIR}
            mkdir -p ${TARGET_HOST_REDUNDANCY_DIR}
        " && \
        scp $CUR_DIR/redundancy/src/redundancy ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
        scp -r $CUR_DIR/fabric_network/deploy/crypto-config ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
        # scp $CUR_DIR/redundancy/hosts_config.sh ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/ > /dev/null 2>&1 && \
        scp $CUR_DIR/cluster_IP.conf ${HOST_USER}@${node}:${TARGET_HOST_REDUNDANCY_DIR}/../ > /dev/null 2>&1 &
        org_id=$((org_id+1))
    done
    wait

    local needCheck="-n"
    # [ $performance = true ] && [ $WRITE = false ] && needCheck=""
    [ $performance = true ] && needCheck=""

    local org_id=0
    for node in ${CEPH_IPs[@]}; do
    # for node in ${CEPH_IPs[0]}; do
        echo "Deploy redundancy on $node"
        ssh $node "
            # bash ${TARGET_HOST_REDUNDANCY_DIR}/hosts_config.sh
            docker exec ceph-demo-${org_id} zsh -c '
                ${TARGET_HOST_REDUNDANCY_DIR}/redundancy \
                    -i $org_id -s $OBJ_SIZE_TO_CEPH $needCheck \
                    -c ${TARGET_HOST_REDUNDANCY_DIR}/../cluster_IP.conf \
                    > ${TARGET_HOST_REDUNDANCY_DIR}/redundancy.log 2>&1 &
            '
        " &
        org_id=$(($org_id+1))
    done
    wait

    echo "Deploy redundancy ... done"
}

gen_rados_objs_to_test() {
    echo "Generate rados objects to test"

    # local org_id=0
    # for node in ${CEPH_IPs[@]}; do
    #     echo "Generate rados objects on $node"
    #     ssh $node "
    #         docker exec ceph-demo-${org_id} zsh -c '
    #             source ~/.zshrc;
    #             ceph osd pool rm testbench testbench --yes-i-really-really-mean-it
    #             ceph osd pool create testbench 32 32
    #             ceph osd pool application enable testbench rgw
    #             rados -p testbench cleanup
    #         '
    #     " &
    #     org_id=$(($org_id+1))
    # done
    # wait
    
    # run rados benchmarks in all orgs
    local org_id=0
    # local obj_size_in_ceph="256K"
    # [ "$performance" = true ] && obj_size_in_ceph="4K"
    for node in ${CEPH_IPs[@]}; do
        if [ $WITH_FABRIC = true ]; then
            echo "Generate rados objects on $node with fabric $GEN_OBJ_TIME seconds"
            ssh $node "
                docker exec ceph-demo-${org_id} zsh -c '
                    source ~/.zshrc;
                    rados bench -p testbench $GEN_OBJ_TIME write -t 1 -b ${OBJ_SIZE_TO_CEPH} --put-hash-to-fabric --no-cleanup \
                        > ./testResult/test_write_${OBJ_SIZE_TO_CEPH}_with_fabric_org${org_id}.res
                '
            " &
        else
            echo "Generate rados objects on $node without fabric $GEN_OBJ_TIME seconds"
            ssh $node "
                docker exec ceph-demo-${org_id} zsh -c '
                    source ~/.zshrc;
                    rados bench -p testbench $GEN_OBJ_TIME write -t 1 -b ${OBJ_SIZE_TO_CEPH} --no-cleanup \
                        > ./testResult/test_write_${OBJ_SIZE_TO_CEPH}_without_fabric_org${org_id}.res
                '
            " &
        fi
        
        org_id=$(($org_id+1))
    done
    wait

    # copy test result to local
    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        if [ $WITH_FABRIC == true ]; then
            scp $HOST_USER@${node}:$CEPH_SRC_DIR/ceph-demo-${org_id}/testResult/test_write_${OBJ_SIZE_TO_CEPH}_with_fabric_org${org_id}.res \
                $CUR_DIR/ceph-config/testResult/test_write_${OBJ_SIZE_TO_CEPH}_with_fabric_org${org_id}.res > /dev/null
        else
            scp $HOST_USER@${node}:$CEPH_SRC_DIR/ceph-demo-${org_id}/testResult/test_write_${OBJ_SIZE_TO_CEPH}_without_fabric_org${org_id}.res \
                $CUR_DIR/ceph-config/testResult/test_write_${OBJ_SIZE_TO_CEPH}_without_fabric_org${org_id}.res > /dev/null
        fi
        org_id=$(($org_id+1))
    done

    echo "Generate rados objects to test ... done"
}

down_redundancy() {
    echo "Down redundancy"

    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        echo "Down redundancy on $node"
        ssh $node "
            docker exec ceph-demo-${org_id} zsh -c '
                kill -9 \$(ps -ef | grep redundancy | grep -v grep | awk \"{print \\\$2}\") > /dev/null 2>&1
            '
        " &
        org_id=$(($org_id+1))
    done
    wait

    echo "Down redundancy ... done"
}

down_kafka() {
    echo "Down kafka cluster"

    local org_id=0
    for node in ${KAFKA_IPs[@]}; do
        echo "Down kafka on $node"
        ssh $node "
            bash ~/deploy-bcs/kafka/down_kafka.sh \
                -p $(($KAFKA_PORT_BASE+$org_id)) \
                -zp $(($ZOOKEEPER_PORT_BASE+$org_id))
        " &
        org_id=$(($org_id+1))
    done
    wait

    echo "Down kafka cluster ... done"
}

down_fabric_network() {
    echo "Down fabric network"

    bash $CUR_DIR/fabric_network/deploy/deploy_fabric_network.sh down

    echo "Down fabric network ... done"
}

down_fabric_sdk() {
    echo "Down fabric-sdk"

    cd $CUR_DIR/fabric_network/deploy
    bash ./deploy_fabric_sdk.sh down

    echo "Down fabric-sdk ... done"
}

down_ceph() {
    echo "Down ceph cluster"

    local org_id=0
    for node in ${CEPH_IPs[@]}; do
        echo "Down ceph on $node"
        ssh $node "
            docker exec ceph-demo-${org_id} zsh -c '
                source ~/.zshrc;
                cd ./build
                bash ../src/stop.sh
                rm -rf out dev
            '
        " &
        org_id=$(($org_id+1))
    done
    wait
}

down_all_cluster() {
    echo "Down all cluster"

    # down redundancy
    down_redundancy

    # down ceph cluster
    down_ceph

    # down fabric-sdk
    down_fabric_sdk

    # down fabric network
    down_fabric_network

    # down kafka cluster
    down_kafka

    echo "Down all cluster ... done"
}

get_hash_in_fabric() {
    local org_id=$1
    local obj_id=$2
    local fabric_sdk_ip=${FABRIC_SDK_IPs[$org_id]}
    local farbic_sdk_port=$(($FABRIC_SDK_PORT_BASE+$org_id))
    local url="http://${fabric_sdk_ip}:${farbic_sdk_port}/get?ID=${org_id}_${obj_id}"
    # echo "Query fabric hash: $url"
    local hash=$(
        curl -s $url | xxd -p -c 32
    )
    echo $hash
}

query_fabric_hash() {
    local org_id=$1
    local org_ip=${CEPH_IPs[$org_id]}
    local all_obj_ids=$(
            ssh $org_ip "
                docker exec ceph-demo-${org_id} zsh -c '
                    source ~/.zshrc;
                    rados -p testbench ls | grep benchmark_data | grep -v "@@"
                ' 2>/dev/null
            "
        )
    local obj_ids=$(echo $all_obj_ids | tr ' ' '\n' | awk -F'object' '{print $2 " " $0}' | sort -n | cut -d' ' -f2- | head -n 10)
    # echo $obj_ids
    
    for obj_id in $obj_ids; do
        local hash=$(get_hash_in_fabric $org_id $obj_id)
        echo "Object [$obj_id] fabric hash: $hash"
    done
}

get_obj() {
    local org_id=$1
    local obj_id=$2
    local ceph_ip=${CEPH_IPs[$org_id]}
    local ceph_port=$(($CEPH_SERVER_PORT_BASE+$org_id))
    local url="http://${ceph_ip}:${ceph_port}/get?oid=${obj_id}"
    echo "Get object: [${obj_id}] from Org_$org_id"
    curl -s $url > ./${obj_id}

    real_hash=$(cal_obj_hash $obj_id)
    fabric_hash=$(get_hash_in_fabric $org_id $obj_id)
    echo "Object [$obj_id] real hash: $real_hash"
    echo "Object [$obj_id] fabric hash: $fabric_hash"
    [ "$real_hash" = "$fabric_hash" ] && echo -e "Object [$obj_id] integrity verification: \e[32mSuccess\e[0m" || echo -e "Object [$obj_id] integrity verification: \e[31mFailed\e[0m"
}

cal_obj_hash() {
    local obj_id=$1
    local obj_hash=""

    # 对于大小为4MB的对象，计算其Merkle根哈希
    if [ $OBJ_SIZE_TO_CEPH -eq $(echo "4*1024*1024" | bc) ]; then
        dd if=$obj_id bs=4K count=1024 2>/dev/null | split -d -a 4 -b 4K - block_
        local i=0
        local j=0
        rm hash_tmp root_hash 2>/dev/null
        for file in block_*; do 
            sha256sum $file | cut -d' ' -f1 | xxd -r -p >> hash_tmp
            rm $file
            j=$((j+1))
            # 若j是32的倍数，i加一
            if [ $((j%32)) -eq 0 ]; then
                # 计算哈希值
                sha256sum hash_tmp | cut -d' ' -f1 | xxd -r -p >> root_hash
                rm hash_tmp
                i=$((i+1))
                j=0
            fi
        done
        
        obj_hash=$(sha256sum root_hash | cut -d' ' -f1)
        rm root_hash
    else
        sha256sum $obj_id | cut -d' ' -f1
    fi
    # echo "Object [$obj_id] real hash: $obj_hash"
    echo $obj_hash
}

test_read_lantency() {
    echo "Test read lantency"

    redundancy_ip=${CEPH_IPs[0]}
    port=10000
    time_total=0.0
    for i in $(seq 0 4); do
        if [ $WITH_FABRIC == true ]; then
            time_cost=$(curl -s http://${redundancy_ip}:${port}/testReadRemoteObj?withHash=true)
            # echo "with fabric: $WITH_FABRIC"
        else
            time_cost=$(curl -s http://${redundancy_ip}:${port}/testReadRemoteObj?withHash=false)
            # echo "without fabric: $WITH_FABRIC"
        fi
        # echo "Read lantency: $time_cost ms"
        time_total=$(echo "$time_total + $time_cost" | bc)
    done
    average_read_latency=$(echo "scale=5; $time_total / 5" | bc)
    local with_fabric="with"
    [ $WITH_FABRIC == false ] && with_fabric="without"
    printf "Read 4MB obj 50 times, average read latency $with_fabric fabric : %.5f ms\n" "$average_read_latency"
}

main() {
    echo "Start deploy bc-storage cluster"
    echo "Performance: $performance"
    cd $CUR_DIR

    # deploy kafka cluster
    deploy_kafka

    # deploy fabric network
    deploy_fabric_network

    # deploy fabric-sdk
    deploy_fabric_sdk

    # deploy ceph cluster
    deploy_ceph

    # deploy redundancy
    deploy_redundancy

    sleep 15s
    
    # # gen rados objects to test
    # gen_rados_objs_to_test

    echo "Deploy bc-storage cluster ... done"
}

# if [ $# -ne 1 ]; then
#     usage
#     exit -1
# fi

while [ $# -ge 1 ]; do
case $1 in
    deploy_performance)
        performance=true
        while [ $# -ge 2 ]; do
            if [ $2 = "without_fabric" ]; then
                WITH_FABRIC=false
            elif [ $2 = "write" ]; then
                WRITE=true
            fi
            shift
        done
        ;;
    deploy_redundancy)
        performance=false
        if [ $# -ge 2 ]; then
            if [ $2 = "without_fabric" ]; then
                WITH_FABRIC=false
            fi
            shift
        fi
        ;;
    down)
        down_all_cluster
        exit 0
        ;;
    gen_obj)
        # performance=false
        while [ $# -ge 2 ]; do
            if [ $2 = "without_fabric" ]; then
                WITH_FABRIC=false
            elif [[ $2 =~ ^[0-9]+$ ]]; then
                GEN_OBJ_TIME=$2
            fi
            shift
        done
        # echo "Generate rados objects to test with $GEN_OBJ_TIME seconds"
        gen_rados_objs_to_test
        exit 0
        ;;
    query_fabric_hash)
        org_id=0
        while [ $# -ge 2 ]; do
            if [[ $2 =~ ^[0-9]+$ ]]; then
                org_id=$2
            fi
            shift
        done
        query_fabric_hash $org_id
        exit 0
        ;;
    get_obj)
        get_obj $2 $3 # read obj from org_id, obj_id
        exit 0
        ;;
    cal_obj_num)
        bash $CUR_DIR/ceph-config/redundancy_valid.sh
        exit 0
        ;;
    get_write_res)
        bash $CUR_DIR/ceph-config/testResult/grep_res.sh $OBJ_SIZE_TO_CEPH
        exit 0
        ;;
    test_read_lantency)
        if [ $# -ge 2 ]; then
            if [ $2 = "without_fabric" ]; then
                WITH_FABRIC=false
            fi
            shift
        fi
        test_read_lantency
        exit 0
        ;;
    deploy_fabric_network)
        down_all_cluster
        if [ $# -ge 2 ]; then
            if [ $2 = "down" ]; then
                exit 0
            fi
        fi
        deploy_fabric_network
        exit 0
        ;;
    test_fabric_tps)
        while [ $# -ge 2 ]; do
            if [[ $2 =~ ^[0-9]+$ ]]; then
                objNum=$2
            fi
            shift
        done
        bash $CUR_DIR/fabric_network/deploy/deploy_fabric_sdk.sh bench $objNum
        exit 0
        ;;
    upload_data_to_fabric)
        while [ $# -ge 2 ]; do
            if [[ $2 =~ ^[0-9]+$ ]]; then
                objNum=$2
                objNum=$(($objNum/4))
            fi
            shift
        done
        bash $CUR_DIR/fabric_network/deploy/deploy_fabric_sdk.sh bench $objNum
        exit 0
        ;;
    *)
        usage
        exit -1
esac
shift
done

main